var filePath = require("../file-path");
let exec = require("child_process").exec;
const fs = require("fs");
let os = require("os");
class Util {
  constructor() {
    console.log("create class Util");
    this.crc_ccitt_table = [
      // CRC余式表
      0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108,
      0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210,
      0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b,
      0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
      0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee,
      0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6,
      0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d,
      0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
      0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5,
      0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc,
      0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4,
      0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
      0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13,
      0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a,
      0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e,
      0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
      0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1,
      0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb,
      0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0,
      0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
      0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657,
      0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9,
      0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882,
      0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
      0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e,
      0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07,
      0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d,
      0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
      0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
    ];
    this.EventTypes = {
      EventTypeTick: "mainTick",
      MainTickTime: 1,
      LocationRecord: "LocationRecord",
    };
    this.LocationEngineType = {
      Invalid: 0,
      BLE_Beacon: 1, //信标定位
      LF: 2,
      BLE_Station: 3, //基站定位
      UWB: 4,
    };
    this.YZ2Packet81Mask = {
      CLA_LOCATION: 8,
      INS_PING: 0,
      INS_HF24G: 1, //自定义2.4G
      INS_BT: 2, //标准蓝牙ibeacon
      HEADMASK_SYSTEMID: 0x01,
      HEADMASK_SRC_ADDR: 0x02,
      HEADMASK_TRG_ADDR: 0x04,
      HEADMASK_RSSI: 0x10,
      MAX_LEN: 100,
    };
    this.GateSideEnum = {
      Unknown: 0,
      Inside: 1,
      GateInside: 2,
      Gate: 3,
      GateOutside: 4,
      Outside: 5,
    };
    this.DftRssiM = 63;
    this.DftRssiN = 450;
  }

  ReverseBits(bytIn) {
    let bytResult = 0;
    if ((bytIn & 0x01) != 0) {
      bytResult |= 0x80;
    }
    if ((bytIn & 0x02) != 0) {
      bytResult |= 0x40;
    }
    if ((bytIn & 0x04) != 0) {
      bytResult |= 0x20;
    }
    if ((bytIn & 0x08) != 0) {
      bytResult |= 0x10;
    }
    if ((bytIn & 0x10) != 0) {
      bytResult |= 0x08;
    }
    if ((bytIn & 0x20) != 0) {
      bytResult |= 0x04;
    }
    if ((bytIn & 0x40) != 0) {
      bytResult |= 0x02;
    }
    if ((bytIn & 0x80) != 0) {
      bytResult |= 0x01;
    }
    return bytResult;
  }
  GetCrc16L(DataBuff, nIndex, nCount) {
    let crc16;
    let crc_l, crc_h;
    let da;
    crc16 = 0;
    for (let i = 0; i < nCount; i++) {
      da = crc16 >> 8; // 以8位二进制数的形式暂存CRC的高8位
      crc16 = crc16 << 8; //左移8位,相当于CRC的低8位乘以
      console.log(
        "res:",
        DataBuff,
        " ",
        DataBuff[nIndex + i],
        "  ",
        da ^ this.ReverseBits(DataBuff[nIndex + i]),
        " ",
        this.crc_ccitt_table[da ^ this.ReverseBits(DataBuff[nIndex + i])]
      );
      crc16 ^=
        this.crc_ccitt_table[da ^ this.ReverseBits(DataBuff[nIndex + i])]; //高8位和当前字节相加后再查表求CRC ，再加上以前的CRC
      crc16 &= 0xffff;
    }
    console.log("crc16:", crc16);
    crc_h = this.ReverseBits(crc16);
    crc_l = this.ReverseBits(crc16 >> 8);
    return crc_l + crc_h * 256;
  }

  GetJsonObj(fileName) {
    var configObj = null;
    try {
      if (fs.existsSync(fileName)) {
        let data = fs.readFileSync(fileName, "utf-8");
        configObj = JSON.parse(data);
      }
    } catch (e) {
      console.log("GetJsonObj error:", e);
    }
    return configObj;
  }
  StrIp2Buffer(str_ip) {
    //"192.168.1.255"
    let list_ip = str_ip.split(".");
    let buf_ip = Buffer.alloc(4);
    for (let i = 0; i < 4; i++) {
      buf_ip[i] = Number(list_ip[i]);
    }
    return buf_ip;
  }
  Bytes2HexString(b, bLowerFirst = true) {
    let hexs = "";
    if (!bLowerFirst) {
      for (let i = b.length - 1; i > -1; i--) {
        let hex = b[i].toString(16);
        if (hex.length == 1) {
          hex = "0" + hex;
        }
        hexs += hex;
      }
    } else {
      for (let i = 0; i < b.length; i++) {
        let hex = b[i].toString(16);
        if (hex.length == 1) {
          hex = "0" + hex;
        }
        hexs += hex;
      }
    }
    return hexs;
  }
  Hexstring2Buffer(str) {
    let pos = 0;
    let len = str.length;
    if (len % 2 != 0) {
      return null;
    }
    len /= 2;
    let hexA = new Array();
    for (let i = 0; i < len; i++) {
      let s = str.substr(pos, 2);
      let v = parseInt(s, 16);
      hexA.push(v);
      pos += 2;
    }
    let buf = Buffer.from(hexA);
    return buf;
  }
  BytesToUInt32(arrByte, index = 0, bLowerFirst = true) {
    if (bLowerFirst) {
      return (
        arrByte[index] +
        arrByte[1 + index] * 256 +
        arrByte[2 + index] * 65536 +
        arrByte[3 + index] * 65536 * 256
      );
    } else {
      return (
        arrByte[index] * 65536 * 256 +
        arrByte[1 + index] * 65536 +
        arrByte[2 + index] * 256 +
        arrByte[3 + index]
      );
    }
  }
  ParseJson(buf) {
    try {
      let obj = JSON.parse(buf, function (key, val) {
        return val;
      });
      return obj;
    } catch (e) {
      console.log(e);
      return null;
    }
  }
  GetNowTime() {
    var myDate = new Date();
    myDate.toLocaleString(); //获取日期与时间
  }

  stringFormat() {
    if (arguments.length == 0) return null;
    var str = arguments[0];
    for (var i = 1; i < arguments.length; i++) {
      var re = new RegExp("\\{" + (i - 1) + "\\}", "gm");
      str = str.replace(re, arguments[i]);
    }
    return str;
  }

  Int2LenHexString(data, len = 0) {
    let str;
    if (data == null) {
      return null;
    }
    str = data.toString(16);
    if (len == 0) {
      return str;
    }
    for (var i = 0; i < len; i++) {
      str = "0" + str;
    }
    str = str.slice(-16);
    return str;
  }
  //生成数据库时间戳
  BuildDBMark() {
    //最大40年
    let now = new Date();
    let s =
      (now.getHours() * 60 + now.getMinutes() * 60 + now.getSeconds()) / 8.64;
    return (
      ((now.getFullYear() - 2000) * 10000 +
        now.getMonth() * 100 +
        now.getDay()) *
        10000 +
      parseInt(s)
    );
  }
  DelayPromise(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }
  async Delay(ms) {
    await this.DelayPromise(ms);
    // let promise=this.DelayPromise(ms);
    // await promise;
    // promise=null;
  }
  GetDistance(r1, r2) {
    //两点之间的距离
    return Math.sqrt(
      (r1.X - r2.X) * (r1.X - r2.X) + (r1.Y - r2.Y) * (r1.Y - r2.Y)
    );
  }
  GetCenter(deviceVertexes) {
    let count = 0;
    let pos = { X: 0, Y: 0 };
    for (let i = 0; i < deviceVertexes.length; i++) {
      if (deviceVertexes[i] != null) {
        pos.X += deviceVertexes[i].x;
        pos.Y += deviceVertexes[i].y;
        count++;
      }
    }
    pos.X = pos.X / count;
    pos.Y = pos.Y / count;
    return pos;
  }
  RssiToDistance(rssi, rssiM = 0, rssiN = 0) {
    if (rssiM == 0) {
      rssiM = this.DftRssiM;
    }
    if (rssiN == 0) {
      rssiN = this.DftRssiN;
    }
    return Math.pow(10, (rssi - rssiM) / (rssiN / 10.0)); //单位米
  }
  GetAverage(intensityList) {
    let count = 0;
    let total = 0;
    for (let i = 0; i < intensityList.length; i++) {
      if (intensityList[i] == 0) continue;
      total += intensityList[i];
      count++;
    }
    return total / count;
  }
  GetBleWeight(intensityList) {
    let weightList = [];
    let total = 0;
    let average = this.GetAverage(intensityList);
    for (let i = 0; i < intensityList.length; i++) {
      if (intensityList[i] == 0) continue;
      if (intensityList[i] < average) {
        total += 1.0 / (intensityList[i] - 800); //加强短距敏感度
      } else {
        total += 1.0 / (intensityList[i] + 800); //加强短距敏感度
      }
    }
    for (let i = 0; i < intensityList.length; i++) {
      if (intensityList[i] == 0) continue;
      if (intensityList[i] < average) {
        weightList[i] = 1.0 / (intensityList[i] - 800) / total; //加强短距敏感度
      } else {
        weightList[i] = 1.0 / (intensityList[i] + 800) / total;
      }
    }
    return weightList;
  }

  SyncRunCmd(cmdStr, timeout = 10000) {
    return new Promise((resolve, reject) => {
      try {
        let time = setTimeout(() => {
          resolve(null);
        }, timeout);

        exec(cmdStr, function (err, stdout, srderr) {
          clearTimeout(time);
          if (err) {
            console.log(err);
            reject(null);
          } else {
            resolve(stdout);
          }
        });
      } catch (e) {
        console.log(e);
        reject(null);
      }
    });
  }
  GetUDPServiceIp() {
    if (os.platform() != "linux") {
      return "192.168.230.1";
    } else {
      return "0.0.0.0";
    }
  }
}
module.exports = new Util();
